from typing import List, Optional, Dict, Any, Union
from pydantic import BaseModel, Field, validator, constr, PositiveInt, PositiveFloat
from datetime import datetime
from enum import Enum
from uuid import UUID

from server.schemas.base import BaseSchema, DateTimeModelMixin, IDModelMixin
from server.schemas.user import UserBriefResponse

class ServerStatus(str, Enum):
    """服务器状态枚举"""
    STOPPED = "stopped"
    RUNNING = "running"
    STARTING = "starting"
    STOPPING = "stopping"
    ERROR = "error"
    INSTALLING = "installing"
    BACKING_UP = "backing_up"
    RESTORING = "restoring"
    UPDATING = "updating"

class ServerType(str, Enum):
    """服务器类型枚举"""
    DEDICATED = "dedicated"
    LOCAL = "local"
    CLOUD = "cloud"

class ServerConfigBase(BaseModel):
    """服务器配置基础模型"""
    config_key: str = Field(..., min_length=1, max_length=50, description="配置键")
    config_value: str = Field(..., description="配置值")
    category: str = Field("general", max_length=50, description="配置类别")
    description: Optional[str] = Field(None, max_length=500, description="配置描述")
    is_custom: bool = Field(False, description="是否自定义配置")

class ServerConfigCreate(ServerConfigBase):
    """创建服务器配置模型"""
    server_id: int = Field(..., description="服务器ID")

class ServerConfigUpdate(BaseModel):
    """更新服务器配置模型"""
    config_value: Optional[str] = Field(None, description="配置值")
    category: Optional[str] = Field(None, max_length=50, description="配置类别")
    description: Optional[str] = Field(None, max_length=500, description="配置描述")
    is_custom: Optional[bool] = Field(None, description="是否自定义配置")

class ServerConfigResponse(ServerConfigBase, IDModelMixin, DateTimeModelMixin):
    """服务器配置响应模型"""
    server_id: int = Field(..., description="服务器ID")

    class Config:
        orm_mode = True

class ServerBackupBase(BaseModel):
    """服务器备份基础模型"""
    name: Optional[str] = Field(None, max_length=100, description="备份名称")
    compression: str = Field("zstd", max_length=20, description="压缩算法")
    exclude_patterns: Optional[List[str]] = Field(None, description="排除模式")
    is_auto: bool = Field(False, description="是否自动备份")
    retention_days: int = Field(7, ge=1, le=365, description="保留天数")

class ServerBackupCreate(ServerBackupBase):
    """创建服务器备份模型"""
    server_id: int = Field(..., description="服务器ID")
    auto_cleanup: bool = Field(True, description="是否自动清理旧备份")

class ServerBackupResponse(ServerBackupBase, IDModelMixin, DateTimeModelMixin):
    """服务器备份响应模型"""
    server_id: int = Field(..., description="服务器ID")
    backup_path: str = Field(..., description="备份路径")
    size: int = Field(..., description="备份大小(字节)")
    version: Optional[str] = Field(None, description="游戏版本")
    status: str = Field(..., description="备份状态")
    duration: Optional[int] = Field(None, description="备份耗时(秒)")
    created_by: int = Field(..., description="创建者ID")
    checksum: Optional[str] = Field(None, description="校验和")
    created_user: Optional[UserBriefResponse] = Field(None, description="创建者信息")

    class Config:
        orm_mode = True

class ServerModBase(BaseModel):
    """服务器模组基础模型"""
    mod_id: str = Field(..., max_length=50, description="模组ID")
    name: str = Field(..., max_length=100, description="模组名称")
    version: Optional[str] = Field(None, max_length=20, description="模组版本")
    enabled: bool = Field(True, description="是否启用")
    load_order: int = Field(0, ge=0, description="加载顺序")

class ServerModCreate(ServerModBase):
    """创建服务器模组模型"""
    server_id: int = Field(..., description="服务器ID")
    workshop_id: Optional[str] = Field(None, max_length=50, description="Steam Workshop ID")
    url: Optional[str] = Field(None, description="模组下载URL")
    local_path: Optional[str] = Field(None, description="本地路径")

    @validator('workshop_id', 'url', 'local_path')
    def check_source(cls, v, values, **kwargs):
        field = kwargs['field']
        other_fields = ['workshop_id', 'url', 'local_path']
        other_fields.remove(field.name)

        # 确保至少提供一个来源
        if v is None:
            if all(values.get(f) is None for f in other_fields):
                raise ValueError('必须提供Workshop ID、URL或本地路径之一')
        return v

class ServerModUpdate(BaseModel):
    """更新服务器模组模型"""
    name: Optional[str] = Field(None, max_length=100, description="模组名称")
    version: Optional[str] = Field(None, max_length=20, description="模组版本")
    enabled: Optional[bool] = Field(None, description="是否启用")
    load_order: Optional[int] = Field(None, ge=0, description="加载顺序")

class ServerModResponse(ServerModBase, IDModelMixin, DateTimeModelMixin):
    """服务器模组响应模型"""
    server_id: int = Field(..., description="服务器ID")
    file_path: Optional[str] = Field(None, description="本地文件路径")
    workshop_id: Optional[str] = Field(None, description="Steam Workshop ID")
    hash: Optional[str] = Field(None, description="文件哈希")
    size: Optional[int] = Field(None, description="文件大小(字节)")

    class Config:
        orm_mode = True

class ServerStatusHistoryResponse(IDModelMixin, DateTimeModelMixin):
    """服务器状态历史响应模型"""
    server_id: int = Field(..., description="服务器ID")
    old_status: str = Field(..., description="旧状态")
    new_status: str = Field(..., description="新状态")
    duration: Optional[int] = Field(None, description="持续时间(秒)")
    changed_by: Optional[int] = Field(None, description="变更者ID")
    comment: Optional[str] = Field(None, description="备注")
    changed_user: Optional[UserBriefResponse] = Field(None, description="变更者信息")

    class Config:
        orm_mode = True

class ServerBase(BaseModel):
    """服务器基础模型"""
    name: str = Field(..., max_length=100, description="服务器名称")
    description: Optional[str] = Field(None, description="服务器描述")
    type: ServerType = Field(ServerType.DEDICATED, description="服务器类型")
    ip: str = Field(..., description="服务器IP地址")
    port: int = Field(8211, ge=1, le=65535, description="游戏端口")
    rcon_port: int = Field(25575, ge=1, le=65535, description="RCON端口")
    rcon_password: str = Field(..., min_length=4, max_length=50, description="RCON密码")
    max_players: int = Field(32, ge=1, le=100, description="最大玩家数")
    install_path: str = Field(..., description="安装路径")
    steam_app_id: int = Field(2394010, description="Steam应用ID")
    steam_branch: str = Field("public", max_length=50, description="Steam分支")
    auto_start: bool = Field(False, description="是否开机自启")
    cpu_limit: Optional[PositiveFloat] = Field(None, description="CPU限制(核心数)")
    memory_limit: Optional[PositiveInt] = Field(None, description="内存限制(MB)")
    bandwidth_limit: Optional[PositiveInt] = Field(None, description="带宽限制(Kbps)")
    is_public: bool = Field(False, description="是否公开服务器")
    public_description: Optional[str] = Field(None, description="公开服务器描述")
    public_image: Optional[str] = Field(None, description="公开服务器图片")
    validate_install: bool = Field(True, description="安装时验证文件")
    auto_install: bool = Field(True, description="是否自动安装")

    @validator('ip')
    def validate_ip(cls, v):
        import re
        ip_pattern = re.compile(r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$')
        if not ip_pattern.match(v) and v != '0.0.0.0':
            raise ValueError('无效的IP地址格式')
        return v

class ServerCreate(ServerBase):
    """创建服务器模型"""
    pass

class ServerUpdate(BaseModel):
    """更新服务器模型"""
    name: Optional[str] = Field(None, max_length=100, description="服务器名称")
    description: Optional[str] = Field(None, description="服务器描述")
    ip: Optional[str] = Field(None, description="服务器IP地址")
    port: Optional[int] = Field(None, ge=1, le=65535, description="游戏端口")
    rcon_port: Optional[int] = Field(None, ge=1, le=65535, description="RCON端口")
    rcon_password: Optional[str] = Field(None, min_length=4, max_length=50, description="RCON密码")
    max_players: Optional[int] = Field(None, ge=1, le=100, description="最大玩家数")
    install_path: Optional[str] = Field(None, description="安装路径")
    steam_branch: Optional[str] = Field(None, max_length=50, description="Steam分支")
    auto_start: Optional[bool] = Field(None, description="是否开机自启")
    cpu_limit: Optional[PositiveFloat] = Field(None, description="CPU限制(核心数)")
    memory_limit: Optional[PositiveInt] = Field(None, description="内存限制(MB)")
    bandwidth_limit: Optional[PositiveInt] = Field(None, description="带宽限制(Kbps)")
    is_public: Optional[bool] = Field(None, description="是否公开服务器")
    public_description: Optional[str] = Field(None, description="公开服务器描述")
    public_image: Optional[str] = Field(None, description="公开服务器图片")
    validate_install: Optional[bool] = Field(None, description="安装时验证文件")
    executable_path: Optional[str] = Field(None, description="可执行文件路径")
    pid: Optional[int] = Field(None, description="进程ID")
    game_version: Optional[str] = Field(None, description="游戏版本")
    status: Optional[ServerStatus] = Field(None, description="服务器状态")

class ServerStatusUpdate(BaseModel):
    """服务器状态更新响应模型"""
    server_id: int = Field(..., description="服务器ID")
    old_status: str = Field(..., description="旧状态")
    new_status: str = Field(..., description="新状态")
    timestamp: datetime = Field(..., description="状态变更时间")

class ServerBriefResponse(IDModelMixin):
    """服务器简要响应模型"""
    name: str = Field(..., description="服务器名称")
    ip: str = Field(..., description="服务器IP地址")
    port: int = Field(..., description="游戏端口")
    max_players: int = Field(..., description="最大玩家数")
    status: str = Field(..., description="服务器状态")
    type: ServerType = Field(..., description="服务器类型")
    is_public: bool = Field(..., description="是否公开服务器")
    created_at: datetime = Field(..., description="创建时间")

    class Config:
        orm_mode = True

class ServerResponse(ServerBase, IDModelMixin, DateTimeModelMixin):
    """服务器详细响应模型"""
    executable_path: Optional[str] = Field(None, description="可执行文件路径")
    game_version: Optional[str] = Field(None, description="游戏版本")
    status: str = Field(..., description="服务器状态")
    pid: Optional[int] = Field(None, description="进程ID")
    created_by: int = Field(..., description="创建者ID")
    last_start_time: Optional[datetime] = Field(None, description="最后启动时间")
    last_stop_time: Optional[datetime] = Field(None, description="最后停止时间")
    created_user: Optional[UserBriefResponse] = Field(None, description="创建者信息")
    configs: Optional[List[ServerConfigResponse]] = Field(None, description="服务器配置列表")
    mods: Optional[List[ServerModResponse]] = Field(None, description="服务器模组列表")
    status_history: Optional[List[ServerStatusHistoryResponse]] = Field(None, description="服务器状态历史")

    class Config:
        orm_mode = True

class ServerStatisticsResponse(BaseModel):
    """服务器统计信息响应模型"""
    total_servers: int = Field(..., description="服务器总数")
    running_servers: int = Field(..., description="运行中服务器数")
    stopped_servers: int = Field(..., description="已停止服务器数")
    error_servers: int = Field(..., description="错误状态服务器数")
    server_type_stats: Dict[str, int] = Field(..., description="服务器类型统计")
    avg_players: float = Field(..., description="平均玩家数")
    max_players: int = Field(..., description="最大玩家数")
    recent_servers: List[ServerBriefResponse] = Field(..., description="最近更新的服务器")

class ServerLogEntry(BaseModel):
    """服务器日志条目模型"""
    id: int = Field(..., description="日志ID")
    log_type: str = Field(..., description="日志类型")
    log_level: str = Field(..., description="日志级别")
    message: str = Field(..., description="日志消息")
    source: Optional[str] = Field(None, description="日志来源")
    player_id: Optional[str] = Field(None, description="玩家ID")
    player_name: Optional[str] = Field(None, description="玩家名称")
    ip_address: Optional[str] = Field(None, description="IP地址")
    created_at: datetime = Field(..., description="日志时间")
    details: Optional[Dict[str, Any]] = Field(None, description="详细信息")

    class Config:
        orm_mode = True

class ServerLogResponse(BaseModel):
    """服务器日志响应模型"""
    server_id: int = Field(..., description="服务器ID")
    logs: List[ServerLogEntry] = Field(..., description="日志列表")
    total: int = Field(..., description="日志总数")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页条数")
    total_pages: int = Field(..., description="总页数")

class ServerBatchOperation(BaseModel):
    """服务器批量操作模型"""
    server_ids: List[int] = Field(..., min_items=1, description="服务器ID列表")
    operation: str = Field(..., regex=r'^(start|stop|restart|backup)$', description="操作类型")
    params: Optional[Dict[str, Any]] = Field(None, description="操作参数")

class ServerModBatchOperation(BaseModel):
    """服务器模组批量操作模型"""
    server_id: int = Field(..., description="服务器ID")
    mod_ids: List[str] = Field(..., min_items=1, description="模组ID列表")
    operation: str = Field(..., regex=r'^(enable|disable|remove)$', description="操作类型")

class ServerModLoadOrderUpdate(BaseModel):
    """服务器模组加载顺序更新模型"""
    server_id: int = Field(..., description="服务器ID")
    mod_ids: List[str] = Field(..., min_items=1, description="模组ID顺序列表")

class ServerConfigBatchUpdate(BaseModel):
    """服务器配置批量更新模型"""
    server_id: int = Field(..., description="服务器ID")
    configs: Dict[str, str] = Field(..., min_items=1, description="配置键值对")

class ServerSearchResponse(BaseModel):
    """服务器搜索响应模型"""
    servers: List[ServerBriefResponse] = Field(..., description="服务器列表")
    total: int = Field(..., description="服务器总数")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页条数")
    total_pages: int = Field(..., description="总页数")